<?php
/*
 *         Tiny Cache Class 
*/

class cache {

    private $work_dir;
    private $c_file;
    private $url;
    private $cache_ttl;
    private $is_partial;
    private $is_cache_alive;

    public function __construct($path_to_cache, $time_to_live = 600) {
        $this->work_dir = $path_to_cache;
        $this->cache_ttl = $time_to_live;
    }


   /*
    *
    * ф-я проверки жизни кеша, если найдет живой кеш, вернет
    * вернет содержимое и , в случае полного кеширования страницы,
    * прервет выполнение сценария
    *
    */

    private function page_check_cache() {
	if(file_exists($this->work_dir.$this->c_file)) {
		$last_mod = filemtime($this->work_dir.$this->c_file);
		$today = intval(date('w',mktime()));
		$mod_day = intval(date('w',$last_mod));
		if($last_mod<mktime() - $this->cache_ttl || $mod_day<$today) {
			return FALSE;
		}
		else {
                    echo file_get_contents($this->work_dir.$this->c_file);
                    if(!$this->is_partial) {
                        exit();
                    }
                    else {
                        $this->is_cache_alive = true;
                        return TRUE;
                    }
		}
	}
	else { return FALSE; }
    }


    /*
    *
    * Если передать в page_cache_start id куска страницы.
    * ф-я будет кешировать конкретный кусок, но не всю страницу.
    * + в таком случае выполнения сценария прервано не будет.
    *
    * ----------------------- крайне нежелательны вложения функций
    *
    */

    public function page_cache_start($part_id = false, $static_name = '') {
       $this->url = $_SERVER['REQUEST_URI'];
       if(!$part_id) {
            $this->c_file = md5(md5($this->url));
            $this->is_partial = false;
        }
        else {
            $this->c_file = md5(md5($this->url).$part_id);
            $this->is_partial = true;
        }
	if($static_name!='') {
            $this->c_file = md5(md5($static_name).$part_id);
	}
	$path = $this->work_dir.substr($this->c_file,0,2);
        if(!is_dir($path)){
            mkdir($path);
        }
        $this->c_file = substr($this->c_file,0,2).'/'.$this->c_file;
    	if(!$this->page_check_cache($static_name)) {
            $this->is_cache_alive = FALSE;
            ob_start();
            return FALSE;
	}
	else {
            return TRUE;
	}
    }

    public function page_cache_end() {
        if(!$this->is_cache_alive) {
            $buf = ob_get_flush();
            file_put_contents($this->work_dir.$this->c_file, $buf, LOCK_EX);
        }
    }

    /*
    *
    * функция для очистки кеша от устаревших файлов
    *
    */

    public function clean_cache() {
	$dir = opendir($this->work_dir);
	while($file = readdir($dir)) {
            if(!is_file($this->work_dir.$file) && $file!='.' && $file!='..') {
		$sub_dir = opendir($this->work_dir.$file);
                while($sub_file = readdir($sub_dir)){
                    $sub_path = $this->work_dir.$file.'/'.$sub_file;
                    if(is_file($sub_path)) $last_mod = filemtime($sub_path);
                        if($last_mod<mktime() - $this->cache_ttl) {
                            unlink($sub_path);
                        }
                }
            }
        }
    	closedir($dir);
    }

    /*
    *
    * ф-я полной очистки кеша
    *
    */

    public function clear_cache() {
	$dir = opendir($this->work_dir);
	while($file = readdir($dir)) {
            if(!is_file($this->work_dir.$file) && $file!='.' && $file!='..') {
		$sub_dir = opendir($this->work_dir.$file);
                while($sub_file = readdir($sub_dir)){
                    $sub_path = $this->work_dir.$file.'/'.$sub_file;
                    if(is_file($sub_path)) {
                          unlink($sub_path);
                    }
                    closedir($sub_dir);
                    rmdir($this->work_dir.$file);
		}
            }
        }
        closedir($dir);
    }
}

?>
